﻿using System;
using System.Runtime.InteropServices;
using RapidDownloader.Model.Helpers;

namespace RapidDownloader.Model
{
    public static class KnownFolders
    {
        #region PInvoke

        [DllImport("shell32.dll")]
        private static extern int SHGetKnownFolderPath([MarshalAs(UnmanagedType.LPStruct)] Guid rfid, uint dwFlags, IntPtr hToken, out IntPtr pszPath);

        #endregion

        #region Fields

        private static readonly Func<Guid, string> foldersCache;
        private static bool functionAvailable = true;

        public static readonly Guid DownloadsFolderId = new Guid(0x374DE290, 0x123F, 0x4565, 0x91, 0x64, 0x39, 0xC4, 0x92, 0x5E, 0x46, 0x7B); // 374DE290-123F-4565-9164-39C4925E467B

        #endregion

        #region Constructors

        static KnownFolders()
        {
            foldersCache = new Func<Guid, string>(id =>
                                                      {
                                                          if (functionAvailable)
                                                          {
                                                              try
                                                              {
                                                                  IntPtr pPath;
                                                                  if (SHGetKnownFolderPath(id, 0, IntPtr.Zero, out pPath) == 0)
                                                                  {
                                                                      var path = Marshal.PtrToStringUni(pPath);
                                                                      Marshal.FreeCoTaskMem(pPath);
                                                                      return path;
                                                                  }
                                                              }
                                                              catch (EntryPointNotFoundException)
                                                              {
                                                                  functionAvailable = false;
                                                              }
                                                          }
                                                          return null;
                                                      }).Memoize();
        }

        #endregion

        #region Properties

        public static string Downloads
        {
            get { return GetFolderPath(DownloadsFolderId); }
        }

        #endregion

        #region Public Methods

        public static string GetFolderPath(Guid guid)
        {
            return foldersCache(guid);
        }

        #endregion
    }
}